////
/// @group icon
////

@use "sass:color";
@use "../spacing";
@use "../theme/theme";
@use "../transition/transition";
@use "../utils";

/// Set to `true` to disable the font icon styles. You normally want to only have
/// one icon type enabled.
///
/// @example scss - Font Icons Only<!-- no-compile -->
///   @use "@react-md/core" with (
///     $disable-svg: true,
///     $disable-symbol: true
///   );
///
/// @type Boolean
$disable-font: false !default;

/// Set to `true` to disable the svg icon styles. You normally want to only have
/// one icon type enabled.
///
/// @example scss - SVG Icons Only<!-- no-compile -->
///   @use "@react-md/core" with (
///     $disable-font: true,
///     $disable-symbol: true
///   );
///
/// @type Boolean
$disable-svg: false !default;

/// Set to `true` to disable the symbol icon styles. You normally want to only have
/// one icon type enabled.
///
/// @example scss - Material Symbols Icons Only<!-- no-compile -->
///   @use "@react-md/core" with (
///     $disable-font: true,
///     $disable-svg: true
///   );
///
/// @type Boolean
$disable-symbol: false !default;

/// Set to `true` to disable the dense icon sizes
/// @type Boolean
$disable-dense: false !default;

/// Set to `true` to disable the styles for aligning icons within inline text
/// blocks (like paragraphs).
/// @type Boolean
$disable-inline: false !default;

/// Set to `true` to disable the styles for inheriting the current color.
///
/// @type Boolean
$disable-current-color: false !default;

/// Set to `true` to disable the `.rmd-icon--before` styles with the
/// `TextIconSpacing` component.
/// @type Boolean
$disable-spacing-before: false !default;

/// Set to `true` to disable the `.rmd-icon--after` styles with the
/// `TextIconSpacing` component.
/// @type Boolean
$disable-spacing-after: false !default;

/// Set to `true` to disable the `.rmd-icon--above` styles with the
/// `TextIconSpacing` component.
/// @type Boolean
$disable-spacing-above: false !default;

/// Set to `true` to disable the `.rmd-icon--below` styles with the
/// `TextIconSpacing` component.
/// @type Boolean
$disable-spacing-below: false !default;

/// Set to `true` to disable the icon rotator styles
/// @type Boolean
$disable-rotator: false !default;

/// The default icon color when using the global light theme
/// @type Color
$light-theme-color: color.adjust(#000, $lightness: 46%) !default;

/// The default icon color when using the global dark theme
/// @type Color
$dark-theme-color: color.adjust(#fff, $lightness: -30%) !default;

/// The default icon color
/// @type Color
$color: theme.get-default-color($light-theme-color, $dark-theme-color) !default;

/// The default icon size
/// @type Number
$size: 1.5rem !default;

/// The default icon dense size
/// @type Number
$dense-size: 1.25rem !default;

/// This is the default material symbol fill value. It should be one of:
/// - `0`
/// - `1`
///
/// @type Number
$symbol-fill: 0 !default;

/// This is the default material symbol weight value. It should be one of:
/// - `100`
/// - `200`
/// - `300`
/// - `400`
/// - `500`
/// - `600`
/// - `700`
///
/// @type Number
$symbol-weight: 400 !default;

/// This is the default material symbol grade value. It should be one of:
/// - `-25`
/// - `0`
/// - `200`
///
/// @type Number
$symbol-grade: 0 !default;

/// This is the default material symbol fill value. It should be one of:
/// - `20`
/// - `24`
/// - `40`
/// - `48`
///
/// @type Number
$symbol-optical-size: 48 !default;

/// @access private
/// @type Number
$_validated-fill: utils.validate((0, 1), $symbol-fill, "$symbol-fill");
/// @access private
/// @type Number
$_validated_weight: utils.validate(
  (100 200 300 400 500 600 700),
  $symbol-weight,
  "$symbol-weight"
);
/// @access private
/// @type Number
$_validated_grade: utils.validate((-25 0 200), $symbol-grade, "$symbol-grade");
/// @access private
/// @type Number
$_validated_optical-size: utils.validate(
  (20 24 40 48),
  $symbol-optical-size,
  "$symbol-optical-size"
);

/// The default spacing for the `TextIconSpacing` component or anytime icons
/// should be separated from other content.
///
/// @type Number
$spacing: spacing.get-var(sm) !default;

/// The default `IconRotator` starting position
/// @type String
$rotate-from: 0deg !default;

/// The default `IconRotator` ending position
/// @type String
$rotate-to: 180deg !default;

/// The default `IconRotator` transition duration
/// @type Number
$rotate-duration: transition.$linear-duration !default;

/// The available configurable css variables and mostly used internally for the
/// `get-var`, `set-var`, and `use-var` utils.
/// @type List
$variables: (
  color,
  size,
  dense-size,
  spacing,
  rotate-from,
  rotate-to,
  symbol-fill,
  symbol-grade,
  symbol-weight,
  symbol-optical-size
);

/// shouldn't really use react-md without icons though...
/// @access private
/// @type Boolean
$_disable-icons: $disable-font and $disable-svg and $disable-symbol;

/// @param {String} name - The supported variable name
/// @param {any} fallback [null] - An optional fallback value
/// @returns {String} a `var()` statement
@function get-var($name, $fallback: null) {
  $var: utils.get-var-name($variables, $name, "icon");
  @if $fallback {
    @return var(#{$var}, #{$fallback});
  }

  @return var(#{$var});
}

/// @param {String} name - The supported variable name
/// @param {any} value - The value to set the variable to. Supports `null` which
/// will just be a no-op.
@mixin set-var($name, $value) {
  @if $value {
    #{utils.get-var-name($variables, $name, "icon")}: #{$value};
  }
}

/// @param {String} property - The css property to apply the variable to
/// @param {String} name [$property] - The supported variable name
/// @param {any} fallback [null] - An optional fallback value if the variable has not
/// been set
@mixin use-var($property, $name: $property, $fallback: null) {
  #{$property}: get-var($name, $fallback);
}

/// Applies the light the variables based on feature flags
@mixin use-light-theme {
  @if not $_disable-icons {
    @include set-var(color, $light-theme-color);
  }
}

/// Applies the dark the variables based on feature flags
@mixin use-dark-theme {
  @if not $_disable-icons {
    @include set-var(color, $dark-theme-color);
  }
}

/// Conditionally applies the css variables based on feature flags
@mixin variables {
  @if not $_disable-icons {
    @include set-var(color, $color);
    @include set-var(size, $size);
    @if not $disable-dense {
      @include set-var(dense-size, $dense-size);
    }
    @include set-var(spacing, $spacing);
  }

  @if not $disable-symbol {
    @include set-var(symbol-fill, $symbol-fill);
    @include set-var(symbol-grade, $symbol-grade);
    @include set-var(symbol-weight, $symbol-weight);
    @include set-var(symbol-optical-size, $symbol-optical-size);
  }

  @if not $disable-rotator {
    @include set-var(rotate-from, $rotate-from);
    @include set-var(rotate-to, $rotate-to);
  }
}

/// Generates all the styles based on feature flags.
///
/// @param {Boolean} disable-layer [false] - Set this to `true` to disable the
/// layer behavior
@mixin styles($disable-layer: false) {
  @if not $_disable-icons {
    @include utils.optional-layer(icon, $disable-layer) {
      @include theme.default-system-theme {
        @include use-dark-theme;
      }

      .rmd-icon {
        @include use-var(font-size, size);
        @include use-var(color);

        // you normally don't want icons to shrink in flex containers.
        // update the icon manually instead.
        flex-shrink: 0;
        user-select: none;

        @if not $disable-font {
          &--font {
            text-align: center;
          }
        }

        @if not $disable-svg {
          &--svg {
            fill: currentcolor;
            height: 1em;
            width: 1em;
          }
        }

        @if not $disable-symbol {
          &--symbol {
            font-variation-settings:
              "FILL" get-var(symbol-fill),
              "wght" get-var(symbol-weight),
              "GRAD" get-var(symbol-grade),
              "opsz" get-var(symbol-optical-size);
          }
        }

        @if not $disable-current-color {
          &--cc {
            @include set-var(color, currentcolor);
          }
        }

        @if not $disable-inline {
          &--vam {
            vertical-align: middle;
          }
        }

        @if not $disable-spacing-before {
          &--before {
            @include use-var(margin-right, spacing);

            @include utils.rtl {
              @include use-var(margin-left, spacing);

              margin-right: 0;
            }
          }
        }

        @if not $disable-spacing-after {
          &--after {
            @include use-var(margin-left, spacing);

            @include utils.rtl {
              @include use-var(margin-right, spacing);

              margin-left: 0;
            }
          }
        }

        @if not $disable-spacing-above {
          &--above {
            @include use-var(margin-bottom, spacing);
          }
        }

        @if not $disable-spacing-below {
          &--below {
            @include use-var(margin-top, spacing);
          }
        }

        @if not $disable-dense {
          &--dense {
            @include set-var(size, get-var(dense-size));
          }
        }
      }
    }

    @if not $disable-rotator {
      .rmd-icon-rotator {
        transform: rotate(get-var(rotate-from));

        &--animate {
          transition: transform $rotate-duration linear;
        }

        &--rotated {
          transform: rotate(get-var(rotate-to));
        }
      }
    }
  }
}
